package com.subl.mybatis.util;

import cn.hutool.core.lang.Snowflake;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Enumeration;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class IdUtils {
    private static final AtomicInteger seq = new AtomicInteger(0);
    public static String genGtrid() {
        String name = getIp();
        if ("".equals(name)) {
            name = getComputerName();
        }
        StringBuilder sb = new StringBuilder();
        sb.append(name)
                .append(":")
                .append(getMinuteOffset())
                .append(":")
                .append(seq.addAndGet(1));
        return sb.toString();
    }
    private static String getIp() {
        InetAddress addr = null;
        try {
            addr = getLocalHostLANAddress().getLocalHost();
            return addr.getHostAddress();
        } catch (UnknownHostException e) {
            return "";
        }
    }
    private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
        try {
            InetAddress candidateAddress = null;
            // 遍历所有的网络接口
            for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
                NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
                // 在所有的接口下再遍历IP
                for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
                    InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
                    if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址
                        if (inetAddr.isSiteLocalAddress()) {
                            // 如果是site-local地址，就是它了
                            return inetAddr;
                        } else if (candidateAddress == null) {
                            // site-local类型的地址未被发现，先记录候选地址
                            candidateAddress = inetAddr;
                        }
                    }
                }
            }
            if (candidateAddress != null) {
                return candidateAddress;
            }
            // 如果没有发现 non-loopback地址.只能用最次选的方案
            InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
            if (jdkSuppliedAddress == null) {
                throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
            }
            return jdkSuppliedAddress;
        } catch (Exception e) {
            UnknownHostException unknownHostException = new UnknownHostException(
                    "Failed to determine LAN address: " + e);
            unknownHostException.initCause(e);
            throw unknownHostException;
        }
    }

    private static String getComputerName() {
        Map<String, String> map = System.getenv();
        String computerName = map.get("COMPUTERNAME");// 获取计算机名
        return computerName;
    }

    private static Long getMinuteOffset() {
        LocalDateTime baseTime = LocalDateTime.of(2022, 1, 1, 0, 0, 0);
        ZonedDateTime zonedDateTime = baseTime.atZone(ZoneId.of("Asia/Shanghai"));
        long baseTimeMillis = zonedDateTime.toInstant().toEpochMilli();
        long currentTimeMillis = System.currentTimeMillis();
        long offsetOfMinute = (currentTimeMillis - baseTimeMillis) / 1000 / 60;
        return offsetOfMinute;
    }


}
